/* eslint-disable no-prototype-builtins */

/**
 * 防抖函数
 */
export function debounce(fn, delay = 500, immediate = false, callBack) {
  let timer = null
  let isInvoke = false

  const _debounce = function (...args) {
    if (timer) clearTimeout(timer)

    if (immediate && !isInvoke) {
      const result = fn.apply(this, args)
      if (callBack) callBack(result)
      isInvoke = true
    } else {
      timer = setTimeout(() => {
        const result = fn.apply(this, args)
        if (callBack) callBack(result)
        isInvoke = false
      }, delay)
    }
  }

  _debounce.cancel = function () {
    if (timer) clearTimeout(timer)
    timer = null
    isInvoke = false
  }

  return _debounce
}

/**
 * 深度合并
 * @param {*} target
 * @param {*} source
 */
const isObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]'
export const deepMerge = (target, source) => {
  if (isObject(target) && isObject(source)) {
    // 遍历源对象，将源对象存在但目标对象不存在的属性赋值给目标对象
    for (const key in source) {
      if (!target.hasOwnProperty(key)) {
        target[key] = source[key]
      }
    }
    // 遍历目标对象
    for (const key in target) {
      if (source.hasOwnProperty(key)) {
        // 判断属性值数据类型，若不是对象类型则赋值给目标对象
        if (!isObject(source[key])) {
          target[key] = source[key]
        } else {
          // 是对象类型则递归调用
          deepMerge(target[key], source[key])
        }
      }
    }
  }
  return target
}
